package com.ruoyi.system.service.impl;

import java.util.*;

import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.system.domain.vo.*;
import com.ruoyi.system.service.ElasticsearchQueryBuilderService;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.PublicOpinionTopicMapper;
import com.ruoyi.system.domain.PublicOpinionTopic;
import com.ruoyi.system.service.IPublicOpinionTopicService;

import static cn.hutool.crypto.SecureUtil.md5;

/**
 * 舆情主题Service业务层处理
 * 
 * @author ruoyi
 * @date 2021-07-14
 */
@Service
public class PublicOpinionTopicServiceImpl implements IPublicOpinionTopicService 
{
    @Autowired
    private PublicOpinionTopicMapper PublicOpinionTopicMapper;
    @Autowired
    private EsUtil esUtil;
    @Autowired
    private ElasticsearchQueryBuilderService elasticsearchQueryBuilderService;

    /**
     * 查询舆情主题
     *
     * @param id 舆情主题ID
     * @return 舆情主题
     */
    @Override
    public PublicOpinionTopic selectPublicOpinionTopicById(Long id)
    {
        return PublicOpinionTopicMapper.selectPublicOpinionTopicById(id);
    }

    /**
     * 查询舆情主题列表
     *
     * @param PublicOpinionTopic 舆情主题
     * @return 舆情主题
     */
    @Override
    @DataScope(deptAlias = "topic",userAlias = "topic")
    public List<PublicOpinionTopic> selectPublicOpinionTopicList(PublicOpinionTopic PublicOpinionTopic)
    {
        return PublicOpinionTopicMapper.selectPublicOpinionTopicList(PublicOpinionTopic);
    }

    /**
     * 新增舆情主题
     *
     * @param PublicOpinionTopic 舆情主题
     * @return 结果
     */
    @Override
    public int insertPublicOpinionTopic(PublicOpinionTopic PublicOpinionTopic)
    {
        return PublicOpinionTopicMapper.insertPublicOpinionTopic(PublicOpinionTopic);
    }

    /**
     * 修改舆情主题
     *
     * @param PublicOpinionTopic 舆情主题
     * @return 结果
     */
    @Override
    public int updatePublicOpinionTopic(PublicOpinionTopic PublicOpinionTopic)
    {
        return PublicOpinionTopicMapper.updatePublicOpinionTopic(PublicOpinionTopic);
    }

    /**
     * 批量删除舆情主题
     *
     * @param ids 需要删除的舆情主题ID
     * @return 结果
     */
    @Override
    public int deletePublicOpinionTopicByIds(Long[] ids)
    {
        return PublicOpinionTopicMapper.deletePublicOpinionTopicByIds(ids);
    }

    @Override
    public List<NameListValue> getSentimentByPublishTimeByTopicId(Long topicId) {
        PublicOpinionTopic topic = PublicOpinionTopicMapper.selectPublicOpinionTopicById(topicId);
        SearchSourceBuilder searchSourceBuilder = esUtil.buildSearchSourceBuilder(topic, null, null, null);
        return esUtil.getCountGroupByPublishDateSentiment(searchSourceBuilder);
    }

    @Override
    public List<NameValue> getKeywordsByTopicId(Long topicId, int i) {
        PublicOpinionTopic topic = PublicOpinionTopicMapper.selectPublicOpinionTopicById(topicId);
        SearchSourceBuilder searchSourceBuilder = esUtil.buildSearchSourceBuilder(topic, null, null, null);
        return esUtil.getCountGroupByKeywords(searchSourceBuilder, i);

    }

    @Override
    public List<NameListValue> getMediaTypeByPublishTimeByTopicId(Long topicId) {
        PublicOpinionTopic topic = PublicOpinionTopicMapper.selectPublicOpinionTopicById(topicId);
        SearchSourceBuilder searchSourceBuilder = esUtil.buildSearchSourceBuilder(topic, null, null, null);
        return esUtil.getCountGroupByPublishDateAndMediaType(searchSourceBuilder);
    }


    @Override
    public List<OpMediaNameSensitiveDayNumVM> countSensitiveOpinionByMediaName(Long topicId) {
        PublicOpinionTopic topic = PublicOpinionTopicMapper.selectPublicOpinionTopicById(topicId);
        SearchSourceBuilder searchSourceBuilder = esUtil.buildSearchSourceBuilder(topic, null, null, null);
        return esUtil.getCountSensitiveOpinionByMediaName(searchSourceBuilder);
    }

    @Override
    public List<OpAuthorSensitiveDayNumVM> countSensitiveAuthorOpinion(Long topicId) {
        PublicOpinionTopic topic = PublicOpinionTopicMapper.selectPublicOpinionTopicById(topicId);
        SearchSourceBuilder searchSourceBuilder = esUtil.buildSearchSourceBuilder(topic, null, null, null);
        return esUtil.getCountSensitiveOpinionByAuthor(searchSourceBuilder);
    }

    @Override
    public OpTypeNumVM getAllInformation(Long topicId) {
        PublicOpinionTopic topic = PublicOpinionTopicMapper.selectPublicOpinionTopicById(topicId);
        SearchSourceBuilder searchSourceBuilder = esUtil.buildSearchSourceBuilder(topic, null, null, null);
        OpTypeNumVM opTypeNumVM = new OpTypeNumVM();
        opTypeNumVM.setAllNum(esUtil.getAllOpinionCount(null));
        opTypeNumVM.setRelatedInformation(esUtil.getAllOpinionCount(searchSourceBuilder));
        opTypeNumVM.setPositive(getPositiveOpinionCount(topic));
        opTypeNumVM.setNeutral(getNeutralOpinionCount(topic));
        opTypeNumVM.setNegative(getNegativeOpinionCount(topic));
        return opTypeNumVM;
    }

    @Override
    public List<NameValue> getPublicOpinionCountGroupByProvinceOfTopicId(Long topicId) {
        PublicOpinionTopic topic = PublicOpinionTopicMapper.selectPublicOpinionTopicById(topicId);
        SearchSourceBuilder searchSourceBuilder = esUtil.buildSearchSourceBuilder(topic, null, null, null);
        return esUtil.getCountGroupByProvince(searchSourceBuilder);
    }

    @Override
    public Map<String,Long> getInteractiveInformation(Long topicId) {
        PublicOpinionTopic topic = PublicOpinionTopicMapper.selectPublicOpinionTopicById(topicId);
        SearchSourceBuilder searchSourceBuilder = esUtil.buildSearchSourceBuilder(topic, null, null, null);
        return esUtil.getInteractiveInformation(searchSourceBuilder);
    }

    @Override
    public Map<String, Long> getInfluenceValue(Long topicId) {
        PublicOpinionTopic topic = PublicOpinionTopicMapper.selectPublicOpinionTopicById(topicId);
        SearchSourceBuilder searchSourceBuilder = esUtil.buildSearchSourceBuilder(topic, null, null, null);
        return esUtil.getInfluenceValue(searchSourceBuilder);
    }

    private long getNegativeOpinionCount(PublicOpinionTopic topic) {
        //用SearchSourceBuilder来构造查询请求体 ,请仔细查看它的方法，构造各种查询的方法都在这。
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //构造QueryBuilder
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        BoolQueryBuilder matchQueryBuilder = elasticsearchQueryBuilderService.boolQueryBuilder(queryBuilder, topic.getSearchArea(), topic.getRelatedWords(), topic.getOpinionWords(),topic.getExclusionWords());
        matchQueryBuilder.must(QueryBuilders.termQuery("isnegative", 1));
        sourceBuilder.query(matchQueryBuilder);
        return esUtil.getAllOpinionCount(sourceBuilder);
    }

    private long getNeutralOpinionCount(PublicOpinionTopic topic) {
        //用SearchSourceBuilder来构造查询请求体 ,请仔细查看它的方法，构造各种查询的方法都在这。
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        BoolQueryBuilder matchQueryBuilder = elasticsearchQueryBuilderService.boolQueryBuilder(queryBuilder, topic.getSearchArea(), topic.getRelatedWords(), topic.getOpinionWords(),topic.getExclusionWords());
        matchQueryBuilder.must(QueryBuilders.termQuery("isneutral", 1));
        sourceBuilder.query(matchQueryBuilder);
        return esUtil.getAllOpinionCount(sourceBuilder);
    }

    private long getPositiveOpinionCount(PublicOpinionTopic topic) {
        //用SearchSourceBuilder来构造查询请求体 ,请仔细查看它的方法，构造各种查询的方法都在这。
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        BoolQueryBuilder matchQueryBuilder = elasticsearchQueryBuilderService.boolQueryBuilder(queryBuilder, topic.getSearchArea(), topic.getRelatedWords(), topic.getOpinionWords(),topic.getExclusionWords());
        matchQueryBuilder.must(QueryBuilders.termQuery("ispositive", 1));
        sourceBuilder.query(matchQueryBuilder);
        return esUtil.getAllOpinionCount(sourceBuilder);
    }


}
